home *** CD-ROM | disk | FTP | other *** search
- /* SDB - expression compiler
- syntax:
- <expr> ::= <lor> <EOS>
- <lor> ::= <land> { '|' <land> }
- <land> ::= <relat> { '&' <relat> }
- <relat> ::= <primary> { <relop> <primary> }
- <primary> ::= <factor> | <unop> <unary>
- <factor> ::= <number> | <string> | '(' <query> ')'
- <number> ::= <digit> | <number> <digit>
- <string> ::= '"' <chars> '"'
- <chars> ::= nil | <chars> <character>
- <relop> ::= '=' | '<>' | '<' | '>' | '<=' | '>='
- <unop> ::= '+' | '-' | '~'
- */
-
- #include "sdbio.h"
-
- extern int dbv_token;
- extern char dbv_tstring[];
- extern int dbv_tvalue;
-
- extern int db_xand();
- extern int db_xor();
- extern int db_xnot();
- extern int db_xlss();
- extern int db_xleq();
- extern int db_xeql();
- extern int db_xgeq();
- extern int db_xgtr();
- extern int db_xneq();
- extern int db_xpush();
- extern int db_xstop();
-
- static union codecell code[CODEMAX+1];
- static int cndx;
- static struct sel *selptr;
-
- /* compile - compile a boolean expression */
- int db_compile(slptr)
- struct sel *slptr;
- {
- int result,i;
- union codecell *cptr;
- #ifdef Lattice
- int (*dns)(); /*dns*/
- #endif
-
- /* save the selection structure pointer */
- selptr = slptr;
-
- /* initialize the code array index */
- cndx = 0;
-
- /* parse the boolean expression */
- if (!expr(&result)) {
- code[cndx++].c_operator = db_xstop;
- freelit(code);
- return (FALSE);
- }
-
- /* terminate the code */
- code[cndx++].c_operator = db_xstop;
-
- /* allocate space for the code array */
- if ((cptr = malloc(sizeof(union codecell) * cndx)) == NULL) {
- freelit(code);
- return (FALSE);
- }
-
- /* store the code into the code array */
- slptr->sl_where = cptr;
- for (i = 0; i < cndx; i++) {
- (*cptr++).c_operator = code[i].c_operator;
- #ifndef Lattice
- if (code[i].c_operator == db_xpush)
- #else
- if ( code[i].c_operator == (dns=db_xpush) ) /*dns*/
- #endif
- (*cptr++).c_operand = code[++i].c_operand;
- }
-
- /* return successfully */
- return (TRUE);
- }
-
- /* db_fcode - free a code array */
- db_fcode(slptr)
- struct sel *slptr;
- {
- /* make sure there is a where clause */
- if (slptr->sl_where == NULL)
- return;
-
- /* free the literals */
- freelit(slptr->sl_where);
-
- /* free the code array */
- free(slptr->sl_where);
- }
-
- /* operator - insert an operator into the code array */
- static int operator(opr)
- int (*opr)();
- {
- /* insert the operator */
- if (cndx < CODEMAX)
- code[cndx++].c_operator = opr;
- else
- return (db_ferror(CDSIZE));
-
- /* return successfully */
- return (TRUE);
- }
-
- /* operand - insert an operand into the code array */
- static int operand(opr)
- struct operand *opr;
- {
- /* insert the push operator */
- if (!operator(db_xpush))
- return (FALSE);
-
- /* insert the operand */
- if (cndx < CODEMAX)
- code[cndx++].c_operand = opr;
- else
- return (db_ferror(CDSIZE));
-
- /* return successfully */
- return (TRUE);
- }
-
- /* expr - compile an expression */
- static int expr(result)
- int *result;
- {
- int lval,rval;
-
- if (!land(&lval))
- return (FALSE);
- while (db_token() == '|') {
- db_ntoken();
- if (!land(&rval))
- return (FALSE);
- if (!operator(db_xor))
- return (FALSE);
- }
- *result = lval;
- return (TRUE);
- }
-
- static int land(result)
- int *result;
- {
- int lval,rval;
-
- if (!relat(&lval))
- return (FALSE);
- while (db_token() == '&') {
- db_ntoken();
- if (!relat(&rval))
- return (FALSE);
- if (!operator(db_xand))
- return (FALSE);
- }
- *result = lval;
- return (TRUE);
- }
-
- static int relat(result)
- int *result;
- {
- int lval,rval;
- int tkn;
-
- if (!primary(&lval))
- return (FALSE);
- while (db_token() <= LSS && dbv_token >= GTR) {
- tkn = db_ntoken();
- if (!primary(&rval))
- return (FALSE);
- switch (tkn) {
- case LSS:
- if (!operator(db_xlss))
- return (FALSE);
- break;
- case LEQ:
- if (!operator(db_xleq))
- return (FALSE);
- break;
- case EQL:
- if (!operator(db_xeql))
- return (FALSE);
- break;
- case NEQ:
- if (!operator(db_xneq))
- return (FALSE);
- break;
- case GEQ:
- if (!operator(db_xgeq))
- return (FALSE);
- break;
- case GTR:
- if (!operator(db_xgtr))
- return (FALSE);
- break;
- }
- }
- *result = lval;
- return (TRUE);
- }
-
- static int primary(result)
- int *result;
- {
- int val;
- int tkn;
-
- if (db_token() == '~') {
- tkn = db_ntoken();
- if (!primary(&val))
- return (FALSE);
- switch (tkn) {
- case '~':
- if (!operator(db_xnot))
- return (FALSE);
- break;
- }
- }
- else
- if (!factor(&val))
- return (FALSE);
- *result = val;
- return (TRUE);
- }
-
- static int factor(result)
- int *result;
- {
- int val;
-
- if (db_token() == '(') {
- db_ntoken();
- if (!expr(&val))
- return (FALSE);
- if (db_token() != ')')
- return (db_ferror(SYNTAX));
- db_ntoken();
- }
- else
- if (!get_operand(&val))
- return (FALSE);
- *result = val;
- return (TRUE);
- }
-
- /* get_operand - get an operand (number, string, or attribute) */
- static int get_operand(result)
- int *result;
- {
- /* determine operand type */
- if (db_ntoken() == NUMBER)
- return (get_number(result));
- else if (dbv_token == ID)
- return (get_attr(result));
- else if (dbv_token == STRING)
- return (get_string(result));
- else
- return (db_ferror(SYNTAX));
- }
-
- /* get_attr - get an attribute argument */
- static int get_attr(result)
- int *result;
- {
- struct operand *opr;
- char rname[RNSIZE+1],aname[ANSIZE+1];
- char *aptr; int atype,alen;
-
- /* save the attribute name */
- stccpy(aname,dbv_tstring,ANSIZE); aname[ANSIZE] = EOS;
-
- /* check for a "." indicating a qualified attribute name */
- if (db_token() == '.') {
- db_ntoken();
-
- /* the previous ID was really a relation name */
- strcpy(rname,aname);
-
- /* check for the real attribute name */
- if (db_ntoken() != ID)
- return (db_ferror(SYNTAX));
-
- /* save the attribute name */
- stccpy(aname,dbv_tstring,ANSIZE); aname[ANSIZE] = EOS;
-
- /* lookup the attribute name */
- if (!db_sattr(selptr,rname,aname,&atype,&aptr,&alen))
- return (FALSE);
- }
- else
- if (!db_sattr(selptr,NULL,aname,&atype,&aptr,&alen))
- return (FALSE);
-
- /* get a new operand structure */
- if ((opr = malloc(sizeof(struct operand))) == NULL)
- return (db_ferror(INSMEM));
-
- /* initialize the new operand structure */
- opr->o_type = ATTR;
- opr->o_value.ov_char.ovc_type = atype;
- opr->o_value.ov_char.ovc_string = aptr;
- opr->o_value.ov_char.ovc_length = alen;
-
- /* insert the operand into the code array */
- if (!operand(opr)) {
- free(opr);
- return (FALSE);
- }
-
- /* store operand type */
- *result = atype;
-
- /* return successfully */
- return (TRUE);
- }
-
- /* get_number - get a numeric operand */
- static int get_number(result)
- int *result;
- {
- struct operand *opr;
-
- /* get a new operand structure */
- if ((opr = malloc(sizeof(struct operand))) == NULL)
- return (db_ferror(INSMEM));
-
- /* initialize the new operand structure */
- opr->o_type = LITERAL;
- if ((opr->o_value.ov_char.ovc_string =
- malloc(strlen(dbv_tstring)+1)) == NULL) {
- free(opr);
- return (db_ferror(INSMEM));
- }
- opr->o_value.ov_char.ovc_type = TNUM;
- strcpy(opr->o_value.ov_char.ovc_string,dbv_tstring);
- opr->o_value.ov_char.ovc_length = strlen(dbv_tstring);
-
- /* insert the operand into the code array */
- if (!operand(opr)) {
- free(opr->o_value.ov_char.ovc_string); free(opr);
- return (FALSE);
- }
-
- /* operand type is number */
- *result = TNUM;
-
- /* return successfully */
- return (TRUE);
- }
-
- /* get_string - get a string operand */
- static int get_string(result)
- int *result;
- {
- struct operand *opr;
-
- /* get a new operand structure */
- if ((opr = malloc(sizeof(struct operand))) == NULL)
- return (db_ferror(INSMEM));
-
- /* initialize the new operand structure */
- opr->o_type = LITERAL;
- if ((opr->o_value.ov_char.ovc_string =
- malloc(strlen(dbv_tstring)+1)) == NULL) {
- free(opr);
- return (db_ferror(INSMEM));
- }
- opr->o_value.ov_char.ovc_type = TCHAR;
- strcpy(opr->o_value.ov_char.ovc_string,dbv_tstring);
- opr->o_value.ov_char.ovc_length = strlen(dbv_tstring);
-
- /* insert the operand into the code array */
- if (!operand(opr)) {
- free(opr->o_value.ov_char.ovc_string); free(opr);
- return (FALSE);
- }
-
- /* operand type is character */
- *result = TCHAR;
-
- /* return successfully */
- return (TRUE);
- }
-
- /* freelit - free the literals in a code array */
- static freelit(cptr)
- union codecell *cptr;
- {
- #ifdef Lattice
- int (*dns)(); /*dns*/
- for (; (*cptr).c_operator != (dns=db_xstop); cptr++) /*dns*/
- if ((*cptr).c_operator == (dns=db_xpush) ) /*dns*/
- #else
- for (; (*cptr).c_operator != db_xstop; cptr++)
- if ((*cptr).c_operator == db_xpush )
- #endif
- if ((*++cptr).c_operand->o_type == LITERAL)
- free((*cptr).c_operand->o_value.ov_char.ovc_string);
- }
-